package com.bianqian.demo.service;

import com.bianqian.demo.dto.*;
import com.bianqian.demo.entity.Category;
import com.bianqian.demo.entity.User;
import com.bianqian.demo.entity.Note;
import com.bianqian.demo.repository.CategoryRepository;
import com.bianqian.demo.repository.NoteRepository;
import com.bianqian.demo.repository.UserRepository;
import com.bianqian.demo.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 笔记服务类
 */
@Service
@Transactional
public class NoteService {
    
    @Autowired
    private NoteRepository noteRepository;
    
    @Autowired
    private CategoryRepository categoryRepository;
    
    
    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserRepository userRepository;
    
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NoteService.class);
    
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 获取笔记列表
     */
    public ApiResponse<NoteListResponse> getNotesList(String token, Integer page, Integer pageSize, 
                                                     String keyword, String category, Boolean pinned) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            // 设置默认分页参数
            if (page == null || page < 1) page = 1;
            if (pageSize == null || pageSize < 1) pageSize = 20;
            
            Pageable pageable = PageRequest.of(page - 1, pageSize);
            Page<Note> notePage;
            
            // 根据条件查询笔记
            if (keyword != null && !keyword.trim().isEmpty()) {
                // 关键词搜索
                notePage = noteRepository.findByUserIdAndKeyword(userId, keyword.trim(), pageable);
            } else if (category != null && !category.trim().isEmpty()) {
                // 分类筛选
                notePage = noteRepository.findByUserIdAndCategoryName(userId, category.trim(), pageable);
            } else if (pinned != null) {
                // 置顶筛选
                notePage = noteRepository.findByUserIdAndIsPinnedAndIsDeletedFalseOrderByCreatedAtDesc(userId, pinned, pageable);
            } else {
                // 默认查询
                notePage = noteRepository.findByUserIdAndIsDeletedFalseOrderByIsPinnedDescCreatedAtDesc(userId, pageable);
            }
            
            // 转换为DTO
            List<NoteDto> noteDtos = notePage.getContent().stream()
                    .map(this::convertToDto)
                    .collect(Collectors.toList());
            
            NoteListResponse response = new NoteListResponse();
            response.setList(noteDtos);
            response.setTotal(notePage.getTotalElements());
            response.setPage(page);
            response.setPageSize(pageSize);
            
            return ApiResponse.success("获取成功", response);
            
        } catch (Exception e) {
            return ApiResponse.error(500, "获取笔记列表失败: " + e.getMessage());
        }
    }
    
    /**
     * 创建笔记
     */
    public ApiResponse<NoteDto> createNote(String token, CreateNoteRequest request) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            // 创建笔记实体
            Note note = new Note();
            note.setUserId(userId);
            note.setTitle(request.getTitle());
            note.setContent(request.getContent());
            note.setIsFavorite(false);
            note.setIsPinned(false);
            note.setIsEncrypted(false);
            note.setIsDeleted(false);
            
            // 处理分类
            if (request.getCategory() != null && !request.getCategory().trim().isEmpty()) {
                Category category = categoryRepository.findByNameAndUserId(request.getCategory().trim(), userId);
                if (category != null) {
                    note.setCategoryId(category.getId());
                }
            }
            
            // 保存笔记
            Note savedNote = noteRepository.save(note);
            
            return ApiResponse.success("创建成功", convertToDto(savedNote));
            
        } catch (Exception e) {
            return ApiResponse.error(500, "创建笔记失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新笔记
     */
    public ApiResponse<NoteDto> updateNote(String token, UpdateNoteRequest request) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            // 查找笔记
            Note note = noteRepository.findById(request.getId()).orElse(null);
            if (note == null || !note.getUserId().equals(userId) || note.getIsDeleted()) {
                return ApiResponse.error(404, "笔记不存在");
            }
            
            // 更新笔记信息
            note.setTitle(request.getTitle());
            note.setContent(request.getContent());
            
            // 处理分类
            if (request.getCategory() != null && !request.getCategory().trim().isEmpty()) {
                Category category = categoryRepository.findByNameAndUserId(request.getCategory().trim(), userId);
                if (category != null) {
                    note.setCategoryId(category.getId());
                } else {
                    note.setCategoryId(null);
                }
            } else {
                note.setCategoryId(null);
            }
            
            // 保存更新
            Note updatedNote = noteRepository.save(note);
            
            return ApiResponse.success("更新成功", convertToDto(updatedNote));
            
        } catch (Exception e) {
            return ApiResponse.error(500, "更新笔记失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除笔记
     */
    public ApiResponse<Void> deleteNote(String token, DeleteNoteRequest request) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            // 查找笔记
            Note note = noteRepository.findById(request.getId()).orElse(null);
            if (note == null || !note.getUserId().equals(userId) || note.getIsDeleted()) {
                return ApiResponse.error(404, "笔记不存在");
            }
            
            // 软删除
            note.setIsDeleted(true);
            noteRepository.save(note);
            
            return ApiResponse.success("删除成功", null);
            
        } catch (Exception e) {
            return ApiResponse.error(500, "删除笔记失败: " + e.getMessage());
        }
    }
    
    /**
     * 置顶/取消置顶笔记
     */
    public ApiResponse<NoteDto> pinNote(String token, PinNoteRequest request) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            // 查找笔记
            Note note = noteRepository.findById(request.getId()).orElse(null);
            if (note == null || !note.getUserId().equals(userId) || note.getIsDeleted()) {
                return ApiResponse.error(404, "笔记不存在");
            }
            
            // 更新置顶状态
            note.setIsPinned(request.getPinned());
            Note updatedNote = noteRepository.save(note);
            
            return ApiResponse.success("操作成功", convertToDto(updatedNote));
            
        } catch (Exception e) {
            return ApiResponse.error(500, "操作失败: " + e.getMessage());
        }
    }
    
    /**
     * 加密笔记
     */
    public ApiResponse<NoteDto> encryptNote(String token, EncryptNoteRequest request) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            // 校验保险箱密码
            User user = userRepository.findById(userId).orElse(null);
            if (user == null) {
                return ApiResponse.error(401, "用户不存在或未登录");
            }
            if (user.getInsurancePassword() == null || user.getInsurancePassword().trim().isEmpty()) {
                return ApiResponse.error(400, "尚未设置保险箱密码");
            }
            if (request.getPassword() == null || !user.getInsurancePassword().equals(request.getPassword())) {
                return ApiResponse.error(403, "保险箱密码错误");
            }
            
            // 查找笔记
            Note note = noteRepository.findById(request.getId()).orElse(null);
            if (note == null || !note.getUserId().equals(userId) || note.getIsDeleted()) {
                return ApiResponse.error(404, "笔记不存在");
            }
            
            // 验证密码（这里简化处理，实际应该验证保险箱密码）
            // 在实际应用中，应该验证用户设置的保险箱密码
            
            // 更新加密状态
            note.setIsEncrypted(request.getEncrypted());
            if (request.getEncrypted()) {
                note.setEncryptedTime(LocalDateTime.now());
            } else {
                note.setEncryptedTime(null);
            }
            
            Note updatedNote = noteRepository.save(note);
            
            return ApiResponse.success("加密成功", convertToDto(updatedNote));
            
        } catch (Exception e) {
            return ApiResponse.error(500, "加密失败: " + e.getMessage());
        }
    }
    
    /**
     * 解密笔记
     */
    public ApiResponse<NoteDto> decryptNote(String token, DecryptNoteRequest request) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            // 校验保险箱密码
            User user = userRepository.findById(userId).orElse(null);
            if (user == null) {
                return ApiResponse.error(401, "用户不存在或未登录");
            }
            if (user.getInsurancePassword() == null || user.getInsurancePassword().trim().isEmpty()) {
                return ApiResponse.error(400, "尚未设置保险箱密码");
            }
            if (request.getPassword() == null || !user.getInsurancePassword().equals(request.getPassword())) {
                return ApiResponse.error(403, "保险箱密码错误");
            }
            
            // 查找笔记
            Note note = noteRepository.findById(request.getId()).orElse(null);
            if (note == null || !note.getUserId().equals(userId) || note.getIsDeleted()) {
                return ApiResponse.error(404, "笔记不存在");
            }
            
            // 验证密码（这里简化处理，实际应该验证保险箱密码）
            // 在实际应用中，应该验证用户设置的保险箱密码
            
            // 更新解密状态
            note.setIsEncrypted(false);
            note.setEncryptedTime(null);
            
            Note updatedNote = noteRepository.save(note);
            
            return ApiResponse.success("解密成功", convertToDto(updatedNote));
            
        } catch (Exception e) {
            return ApiResponse.error(500, "解密失败: " + e.getMessage());
        }
    }
    
    /**
     * 分类笔记
     */
    public ApiResponse<NoteDto> categorizeNote(String token, CategorizeNoteRequest request) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            // 查找笔记
            Note note = noteRepository.findById(request.getId()).orElse(null);
            if (note == null || !note.getUserId().equals(userId) || note.getIsDeleted()) {
                return ApiResponse.error(404, "笔记不存在");
            }
            
            // 查找分类
            Category category = null;
            if (request.getCategoryId() != null) {
                // 优先使用categoryId查找
                category = categoryRepository.findById(request.getCategoryId()).orElse(null);
                if (category != null && !category.getUserId().equals(userId)) {
                    category = null; // 确保分类属于当前用户
                }
            }
            
            if (category == null && request.getCategoryName() != null) {
                // 如果categoryId找不到，使用categoryName查找
                category = categoryRepository.findByNameAndUserId(request.getCategoryName(), userId);
            }
            
            if (category == null && request.getCategoryName() != null) {
                // 如果都找不到，创建新分类
                category = new Category();
                category.setName(request.getCategoryName());
                category.setUserId(userId);
                category.setNoteCount(0);
                category.setCount(0);
                category = categoryRepository.save(category);
            }
            
            // 更新笔记分类
            if (category != null) {
                // 记录原分类ID
                Long oldCategoryId = note.getCategoryId();
                
                // 更新笔记分类
                note.setCategoryId(category.getId());
                Note updatedNote = noteRepository.save(note);
                
                // 更新分类统计
                // 如果原分类存在，更新原分类计数
                if (oldCategoryId != null) {
                    updateCategoryCount(oldCategoryId);
                }
                // 更新新分类计数
                updateCategoryCount(category.getId());
                
                return ApiResponse.success("分类成功", convertToDto(updatedNote));
            } else {
                return ApiResponse.error(404, "分类不存在");
            }
            
        } catch (Exception e) {
            return ApiResponse.error(500, "分类失败: " + e.getMessage());
        }
    }
    
    /**
     * 同步笔记
     */
    public ApiResponse<SyncResponse> syncNotes(String token, SyncNotesRequest request) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            int syncedCount = 0;
            int conflictCount = 0;
            
            // 处理前端传来的笔记列表
            for (NoteSyncDto noteSync : request.getNotes()) {
                try {
                    Note existingNote = null;
                    
                    // 如果笔记有ID，尝试查找现有笔记
                    if (noteSync.getId() != null) {
                        existingNote = noteRepository.findById(noteSync.getId()).orElse(null);
                        if (existingNote != null && !existingNote.getUserId().equals(userId)) {
                            existingNote = null; // 确保笔记属于当前用户
                        }
                    }
                    
                    if (existingNote != null) {
                        // 更新现有笔记
                        existingNote.setTitle(noteSync.getTitle());
                        existingNote.setContent(noteSync.getContent());
                        existingNote.setIsPinned(noteSync.getPinned() != null ? noteSync.getPinned() : false);
                        existingNote.setIsEncrypted(noteSync.getEncrypted() != null ? noteSync.getEncrypted() : false);
                        
                        // 处理分类
                        if (noteSync.getCategory() != null && !noteSync.getCategory().trim().isEmpty()) {
                            Category category = categoryRepository.findByNameAndUserId(noteSync.getCategory().trim(), userId);
                            if (category != null) {
                                existingNote.setCategoryId(category.getId());
                            } else {
                                existingNote.setCategoryId(null);
                            }
                        } else {
                            existingNote.setCategoryId(null);
                        }
                        
                        noteRepository.save(existingNote);
                        syncedCount++;
                    } else {
                        // 创建新笔记
                        Note newNote = new Note();
                        newNote.setUserId(userId);
                        newNote.setTitle(noteSync.getTitle());
                        newNote.setContent(noteSync.getContent());
                        newNote.setIsFavorite(false);
                        newNote.setIsPinned(noteSync.getPinned() != null ? noteSync.getPinned() : false);
                        newNote.setIsEncrypted(noteSync.getEncrypted() != null ? noteSync.getEncrypted() : false);
                        newNote.setIsDeleted(false);
                        
                        // 处理分类
                        if (noteSync.getCategory() != null && !noteSync.getCategory().trim().isEmpty()) {
                            Category category = categoryRepository.findByNameAndUserId(noteSync.getCategory().trim(), userId);
                            if (category != null) {
                                newNote.setCategoryId(category.getId());
                            }
                        }
                        
                        noteRepository.save(newNote);
                        syncedCount++;
                    }
                } catch (Exception e) {
                    conflictCount++;
                    // 记录冲突，但继续处理其他笔记
                }
            }
            
            SyncResponse response = new SyncResponse();
            response.setSyncedCount(syncedCount);
            response.setConflictCount(conflictCount);
            
            return ApiResponse.success("同步成功", response);
            
        } catch (Exception e) {
            return ApiResponse.error(500, "同步失败: " + e.getMessage());
        }
    }
    
    /**
     * 将Note实体转换为NoteDto
     */
    private NoteDto convertToDto(Note note) {
        NoteDto dto = new NoteDto();
        dto.setId(note.getId());
        dto.setUserId(note.getUserId());
        dto.setCategoryId(note.getCategoryId());
        dto.setTitle(note.getTitle());
        dto.setContent(note.getContent());
        dto.setIsFavorite(note.getIsFavorite());
        dto.setIsPinned(note.getIsPinned());
        dto.setIsEncrypted(note.getIsEncrypted());
        dto.setEncryptedTime(note.getEncryptedTime());
        dto.setCreatedAt(note.getCreatedAt());
        dto.setUpdatedAt(note.getUpdatedAt());
        
        // 格式化时间显示
        if (note.getUpdatedAt() != null) {
            dto.setDate(note.getUpdatedAt().format(DATE_FORMATTER));
        } else if (note.getCreatedAt() != null) {
            dto.setDate(note.getCreatedAt().format(DATE_FORMATTER));
        }
        
        // 获取分类名称
        if (note.getCategoryId() != null) {
            Category category = categoryRepository.findById(note.getCategoryId()).orElse(null);
            if (category != null) {
                dto.setCategoryName(category.getName());
            }
        }
        
        return dto;
    }
    
    /**
     * 批量分类笔记
     */
    public ApiResponse<BatchCategorizeResponse> batchCategorizeNotes(String token, BatchCategorizeRequest request) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            // 查找或创建分类
            Category category = categoryRepository.findByNameAndUserId(request.getCategoryName(), userId);
            if (category == null) {
                // 创建新分类
                category = new Category();
                category.setName(request.getCategoryName());
                category.setUserId(userId);
                category.setNoteCount(0);
                category.setCount(0);
                category = categoryRepository.save(category);
            }
            
            List<Long> successNoteIds = new ArrayList<>();
            List<Long> failNoteIds = new ArrayList<>();
            
            // 收集需要更新计数的原分类ID
            Set<Long> affectedCategoryIds = new HashSet<>();
            
            // 批量处理笔记
            for (Long noteId : request.getNoteIds()) {
                try {
                    Note note = noteRepository.findById(noteId).orElse(null);
                    if (note != null && note.getUserId().equals(userId) && !note.getIsDeleted()) {
                        // 记录原分类ID
                        if (note.getCategoryId() != null) {
                            affectedCategoryIds.add(note.getCategoryId());
                        }
                        
                        // 更新笔记分类
                        note.setCategoryId(category.getId());
                        noteRepository.save(note);
                        successNoteIds.add(noteId);
                    } else {
                        failNoteIds.add(noteId);
                    }
                } catch (Exception e) {
                    failNoteIds.add(noteId);
                }
            }
            
            // 更新所有受影响分类的计数
            for (Long categoryId : affectedCategoryIds) {
                updateCategoryCount(categoryId);
            }
            // 更新新分类的计数
            updateCategoryCount(category.getId());
            
            BatchCategorizeResponse response = new BatchCategorizeResponse();
            response.setSuccessCount(successNoteIds.size());
            response.setFailCount(failNoteIds.size());
            response.setSuccessNoteIds(successNoteIds);
            response.setFailNoteIds(failNoteIds);
            
            return ApiResponse.success("批量分类完成", response);
            
        } catch (Exception e) {
            return ApiResponse.error(500, "批量分类失败: " + e.getMessage());
        }
    }
    
    /**
     * 复制笔记
     */
    public ApiResponse<NoteDto> copyNote(String token, CopyNoteRequest request) {
        try {
            // 验证token并获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return ApiResponse.error(401, "登录已过期，请重新登录");
            }
            
            // 查找原笔记
            Note originalNote = noteRepository.findById(request.getId()).orElse(null);
            if (originalNote == null || !originalNote.getUserId().equals(userId) || originalNote.getIsDeleted()) {
                return ApiResponse.error(404, "笔记不存在");
            }
            
            // 创建新笔记
            Note newNote = new Note();
            newNote.setUserId(userId);
            newNote.setCategoryId(originalNote.getCategoryId());
            newNote.setTitle(request.getNewTitle() != null && !request.getNewTitle().trim().isEmpty() 
                ? request.getNewTitle().trim() 
                : originalNote.getTitle() + " 副本");
            newNote.setContent(originalNote.getContent());
            newNote.setIsFavorite(false); // 复制的笔记默认不收藏
            newNote.setIsPinned(false); // 复制的笔记默认不置顶
            newNote.setIsEncrypted(false); // 复制的笔记默认不加密
            newNote.setIsDeleted(false);
            
            // 保存新笔记
            Note savedNote = noteRepository.save(newNote);
            
            // 更新分类统计
            if (newNote.getCategoryId() != null) {
                updateCategoryCount(newNote.getCategoryId());
            }
            
            return ApiResponse.success("复制成功", convertToDto(savedNote));
            
        } catch (Exception e) {
            return ApiResponse.error(500, "复制失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新分类统计
     * @param categoryId 分类ID
     */
    private void updateCategoryCount(Long categoryId) {
        try {
            Long actualCount = noteRepository.countByCategoryId(categoryId);
            categoryRepository.updateCount(categoryId, actualCount.intValue());
        } catch (Exception e) {
            log.error("更新分类统计失败，分类ID：{}", categoryId, e);
        }
    }
}
